Thanks for your interest in HyperCGI. I hope you will find this utility to be helpful.
I originally wrote HyperCGI using parts of Chuck Shotton's Hypercard CGI Demo Stack. Since then it has evolved into a robust CGI handling system. We use it at PrintNet for a variety of services, including our Industry Database. You can check it out at http://www.printnet.com.
The version you are currently looking at (version 1.0) is a little bit disabled compared to what I use personally. I have a more sophisticated version that can keep track of multiple sessions (logins with passwords, etc), but I am still working a lot of bugs out of that, so I didn't include that capability in this publicly-available version. If you like this program and are interested in more sophisticated abilities, let me know and I will work harder at getting them incorporated into the next version.
A little bit of self-indulgent chat
I'm Joe Warmbrodt. I work in the Houston area as a network manager for a service bureau called OneStop Desktop. I also do internet programming and design for our sister company, PrintNet. You can reach me by e-mail at joew@printnet.com.
Why on earth would you want to use Hypercard for something like this?
I like Hypercard. Besides, it's what I know best. Unfortunately, I'm not real experienced in more-sophisticated things like C. I have years of experience in HyperCard programming, it's almost like second nature to me. So when I had to get a searchable database on our web site right away, rather than learn a new environment I stuck with what I new. This stack is the result. I'm also very experienced with Pascal, but I couldn't find enough relevant development tools to complete my project on time. Perhaps if I can get it together, I'll redo portions of this project in Pascal. E-mail me and let me know.
Setting Up
To use HyperCGI, you will need WebStar or MacHTTP running on your computer.
You will also need Hypercard version 2.3. The stack seems to work in version 2.1, but I'm not too sure about its reliability.
In this documentation, I am assuming you are fairly familiar with basic web server terminology, and also pretty familiar with HyperCard and HyperTalk. You will need to know HyperTalk in order to create your own CGI handlers.
Installing it
You will need to rename your Hypercard application to "hypercgi.cgi" and place it (or an alias to it) in your WebStar folder.
You should also move the HTML demo files to your WebStar folder.
To start things up, you should run WebStar, then open the "HyperCGI" stack. To work reliably, the stack needs to be in the foreground. It will sometimes work in the background, but not always. I haven't yet figured out why this happens. Anybody out there with ideas?
Using the Demos
I've created two demos to exercise the two demo handlers included in the stack. The first, SimpleClock, (hypercgi1.html) returns the date and time. The second, Not-So-SimpleClock (hypercgi2.html), returns the date and time but in a fancier way.
OK, How does it work?
When the stack receives an apple event from WebStar, it parses the information and places it in fields on the "Main" card. It always expects to receive 2 vital pieces of information: a field called "selector" and a field called "action." The Selector field should contain the name of a background you have created in HyperCard. The "Action" field should contain the name of a handler that is valid for that background.
The stack then sends the contents of the "Action" field as a hypertalk message to the background specified in the "selector" field. Your handler can refer to the fields on the "main" card for all the information that was passed to the CGI. Actually pretty simple.
The stack also maintains a global container called "theReply." Your handler should put its HTML code response into theReply so the stack can spit it back out to the user.
The CGI contains several functions to simplify the retrieval of information from the "Main" card:
HyperCGI Functions:
function GetValue(theFieldName)
This function returns the value of the HTML input field named theFieldName. In other words, if the HTML form contained an input field called "email," defined in HTML as:
<input name=email type=text>
and the user enters "Slartibartfast@magrathea.com," then the function GetValue("email") will return "Slartibartfast@magrathea.com." This is the main function you should use for getting information about form contents.
A little more about GetValue:
GetValue() gets its information from the "parsed args" field on the "main" card. The values in this field are placed there by the cgiParse function (which is usually called automatically). This field is a list of entries. Each line in the list contains two items. The first item is the name of the variable, and the second item is its value.
So, for example, if the CGI receives three arguments, one called name, one called address and one called idnumber, it will place them in the "parsed args" field. It will look like this:
name,Joe Warmbrodt
address,400 Main Street
idnumber,2000
function cgiParse(theText)
This function takes the raw data that Webstar gives to Hypercard and parses it, converting it to an itemized list and returning it. You generally won't have to call this function at all. I just wanted to let you know what it does, since it's such an important function!
function html(HTMLName)
In HyperCGI, I've created a background called "html." This contains a large scrolling field that you can put various HTML code into. The top of the card contains a "name" field. You can use these cards to create chunks of HTML code. HTML() is how you retrieve the code.
For instance, you can put your main menu into an HTML card and call it "mainmenu." Issuing the command:
put html(mainmenu) into theText
would place that HTML code into the container called theText. Just another shortcut to speed things up.
function prep(theField,theSearch,theReplace)
This one's pretty powerful. It is intended to allow you to preprocess HTML before it goes out. It replaces every occurrence of theSearch in the container theField with theReplace. Check out Not-So-SimpleClock for an example of how to use this.
on AutoFill (no parameters)
Autofill takes all items within a field called "auto" on your card and puts them in fields of the same name. It's intended to save your hands from typing "put getValue(theField) into bg field TheField" for every single field you want to access. Again, see Not-So-SimpleClock for a working example.
function Strip(theText)
Sometimes browsers encode special characters as hexadecimal code. It does this by using the "%xx" format, where xx is the hexadecimal value. Strip() removes all this stuff and returns the actual text.
on PR theText
PR appends a line of text to the end of the theReply global container. This is just a shorthand way of saying
put xxxx after theReply
again, just a labor-saving function. I use it a lot!
SPECIFICALLY how do the demos work?
SimpleClock:
1. I created a background called SimpleClock.
2. In the script for that background, I created a handler called "showTime." It looks like this:
on showTime
global theReply -- so we can access the global variable.
put empty into theReply -- clear it out
pr "The time is:" && the time & "<br>" -- Append the current time
pr "The date is:" && the long date & "<br>" -- append the current date
pr "<br><br>This is an example of HyperCGI by Joe Warmbrodt."
end showTime
It's so simple, I don't think I need to go through it step-by-step. Notice that it puts the response into the "theReply" global container. It also uses a function provided by the stack, PR, that appends information to
the tail end of the "theReply" container. This is provided solely to help speed things up.
Not-So-SimpleClock:
This one does exactly the same thing as SimpleClock, just a little fancier.
1. I created a background called notSimpleClock.
2. On its card, I created the following background fields:
"Auto," containing two lines: "theUserName" and "theColor."
"theUserName," an empty field for use by the handler
"theColor," an empty field for use by the handler
3. the HTML file "HyperCGI2.html" contains some input fields you should know about. The first two are:
4. In the script, I created a handler called "showTime." It looks like this:
on showTime
global theReply
go bg "notSimpleClock" -- must be at the card to complete the handler.
autoFill
put prep(html(theTime),"<!time>",the time) into theNewHTML
put prep(theNewHTML,"<!date>",the long date) into theNewHTML
put prep(theNewHTML,"<!color>",bg field "theColor") into theNewHTML
put prep(theNewHTML,"<!userName>",bg field "theUserName") into theNewHTML
put theNewHTML into theReply
end showTime
Instead of using AutoFill, we could have typed:
put getValue("theUserName") into bg field "theUserName"
put getValue("theColor") into bg field "theColor"
but I think typing "AutoFill" is a lot easier, don't you?
The first "prep" statement takes the HTML from the "theTime" card, finds all occurrences of "<!time>" and replaces them with the actual time. The following "prep" statements do the same thing, except with the date, color and username. Then it puts the result into theReply.
Speed and Compatibility
I haven't had a chance to try this stack on a lot of computers. It has been used on a PowerMac 6100, a PowerMac 7100, and a PowerMac 8500. It runs constantly, 24 hours a day, on our PowerMac 7100 web server.
Hypercard runs more slowly than would a native-compiled CGI application. If you keep your stack size down, and keep the